package com.jzhao.gper.spring.v3.beans.support;

import com.jzhao.gper.spring.v3.beans.config.JZBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @author jzhao
 * @date 2020/4/9 21:37
 */
public class JZBeanDefinitionReader {

    //扫描到的所有类
    private List<String> regitryBeanClasses = new ArrayList<String>();
    private Properties contextConfig = new Properties();

    public JZBeanDefinitionReader(String... configLocations) {
        doLoadConfig(configLocations[0]);
        
        doScanner(contextConfig.getProperty("scanPackage"));
    }

    private void doLoadConfig(String contextConfigLocation) {
        InputStream is = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation.replaceAll("classpath:",""));
        try {
            contextConfig.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null != is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void doScanner(String scanPackage) {
        //path不以’/'开头时，默认是从此类所在的包下取资源；
        //path  以’/'开头时，则是从ClassPath根下获取；
        URL url = this.getClass().getClassLoader().getResource("/"+scanPackage.replaceAll("\\.","/"));
        File classPath = new File(url.getFile());

        for (File file : classPath.listFiles()) {
            if(file.isDirectory()){
                doScanner(scanPackage+"."+file.getName());
            } else {
                if(!file.getName().endsWith(".class")){ continue; }
                String className = scanPackage + "." +file.getName().replace(".class","");
                regitryBeanClasses.add(className);
            }
        }
    }

    public List<JZBeanDefinition> loadBeanDefinitions() {
        List<JZBeanDefinition>  result = new ArrayList<JZBeanDefinition>();
        try {
            for (String className : regitryBeanClasses) {
                Class<?> beanClass = Class.forName(className);

                //如果是接口，直接返回，通过其实现在实例化（如果有抽象类，会怎么样？）
                if(beanClass.isInterface()){ continue; }

                result.add(doCreateBeanDefinition(toLowerFirstCase(beanClass.getSimpleName()),beanClass.getName()));

                for (Class<?> i : beanClass.getInterfaces()) {
                    //一个接口有多个实现类时，这里是否有问题？
                    result.add(doCreateBeanDefinition(i.getName(), beanClass.getName()));
                }
            }
        } catch (Exception e) {
             e.printStackTrace();
        }
        return result;
    }

    private String toLowerFirstCase(String simpleName) {
        char[] chars = simpleName.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }

    private JZBeanDefinition doCreateBeanDefinition(String beanName, String beanClassName) {
        JZBeanDefinition beanDefinition = new JZBeanDefinition();
        beanDefinition.setFactoryBeanName(beanName);
        beanDefinition.setBeanClassName(beanClassName);
        return beanDefinition;
    }

    public Properties getConfig() {
        return this.contextConfig;
    }
}
